#pragma once

#include "pch.h"

GLuint AddShader(GLuint shader_program, const char *shader_text, GLenum shader_type) {
	GLuint shader_obj = glCreateShader(shader_type);

	const GLchar *p[1];
	p[0] = shader_text;
	GLint length[1];
	length[0] = (GLint)strlen(shader_text);
	glShaderSource(shader_obj, 1, p, length);

	glCompileShader(shader_obj);
	GLint success;
	glGetShaderiv(shader_obj, GL_COMPILE_STATUS, &success);
	if (!success) {
		GLchar log[1024];
		glGetShaderInfoLog(shader_obj, sizeof(log), NULL, log);
		fprintf(stderr, "Error comliling shader type %d: '%s'\n", shader_type, log);
	}

	glAttachShader(shader_program, shader_obj);
	return shader_obj;
}

void DeleteShader(GLuint shader_obj) {
	glDeleteShader(shader_obj);
}

void CompileShaders(GLuint shader_program) {
	if (!shader_program) {
		fprintf(stderr, "Error in creating shader program!\n");
		exit(1);
	}

	AddShader(shader_program, shader_program == shaderProgram ? pVS : dbg_pVS, GL_VERTEX_SHADER);
	AddShader(shader_program, pFS, GL_FRAGMENT_SHADER);

	glLinkProgram(shader_program);

	GLint success;
	glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
	if (!success) {
		GLchar log[1024];
		glGetShaderInfoLog(shader_program, sizeof(log), NULL, log);
		fprintf(stderr, "Error linking shaders: '%s'\n", log);
	}

	glValidateProgram(shader_program);

	// glUseProgram(shader_program);

	gWorldLocation = glGetUniformLocation(shader_program, "gWorld");
	verify(gWorldLocation != 0xFFFFFFFF);

	if (shader_program == dbgShaderProgram) {
		gDbgUniqueColor = glGetUniformLocation(shader_program, "gDbgUniqueColor");
		verify(gDbgUniqueColor != 0xFFFFFFFF);
	}
}

inline void InitShaderManager() {
	shaderProgram = glCreateProgram();
	dbgShaderProgram = glCreateProgram();
	CompileShaders(shaderProgram);
	CompileShaders(dbgShaderProgram);
}